
n_fold <- 4
used_method <- 'lambda.1se'

library(data.table)
library(magrittr)
library(glmnet)

# Read data

train_dat <- fread('train.csv', data.table = FALSE)
test_dat <- fread('test.csv', data.table = FALSE)
submit_dat <- fread('sample_submission.csv', data.table = FALSE)

# Data aug

pos_1 <- which(train_dat[,'LVD'] %in% 1)
pos_0 <- which(train_dat[,'LVD'] %in% 0)

if (length(pos_1) >= n_fold) {pos_1 <- pos_1[1:(floor(length(pos_1) / n_fold) * n_fold)]}
if (length(pos_0) >= n_fold) {pos_0 <- pos_0[1:(floor(length(pos_0) / n_fold) * n_fold)]}

pos_1 <- pos_1 %>% rep(., ceiling(length(pos_0) / length(pos_1)))
pos_0 <- pos_0

train_X <- train_dat[c(pos_1, pos_0),-1:-2,drop=FALSE] %>% as.matrix()
train_Y <- train_dat[c(pos_1, pos_0),'LVD',drop=FALSE] %>% as.matrix()

train_foldid <- rep(seq(n_fold), nrow(train_X))[1:nrow(train_X)]

# Search parameter

alpha_range <- seq(0, 1, by = 0.1)
lambda_range <- exp(seq(-9, -1, length.out = 45))

param_list <- list()
sub_model_list <- list()

for (m in alpha_range) {
  
  t1 <- Sys.time()
  message('Alpha = ', m)
  
  cv_fit <- cv.glmnet(x = train_X, y = train_Y, family = 'binomial', lambda = lambda_range, alpha = m, type.measure = "auc", foldid = train_foldid, parallel = TRUE)
  param_list[[length(param_list) + 1]] <- data.frame(alpha = m, auc = max(cv_fit[['cvm']]), lambda = cv_fit[[used_method]])
  sub_model_list[[length(sub_model_list) + 1]] <- cv_fit
  
  print(param_list[[length(param_list)]])
  message('time = ', formatC(as.numeric(Sys.time() - t1, unit = 'mins'), format = 'f', 1), ' mins')
  
}

param_data <- do.call('rbind', param_list)
best_model <- sub_model_list[[which.max(param_data[,'auc'])]]

# Get best model

model_coef <- coef.cv.glmnet(best_model, s = used_method) %>% as.matrix()

# Get prediction

test_X <- test_dat[,-1,drop=FALSE] %>% as.matrix()
submit_dat[,'p_LVD'] <- (cbind(1, test_X) %*% model_coef) %>% as.numeric()

# Write out

fwrite(submit_dat, file = 'my_submission.csv', na = '', row.names = FALSE, quote = FALSE)

